package com.weiyi.weiman.quartz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.weiyi.weiman.domain.Const.ComicsConst;
import com.weiyi.weiman.domain.Const.UserConst;
import com.weiyi.weiman.mapper.user.ComicsCollectMapper;
import com.weiyi.weiman.mapper.user.UserBrowseHistoryMapper;
import com.weiyi.weiman.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import user.ComicsCollect;
import user.User;
import user.UserBrowseHistory;

import java.util.*;

/**
 * @Author zhang
 * @Date 2021/5/16 下午8:43
 * @Description 用户漫画信息的定时任务类
 * @Version 1.0
 **/
@Component
@Slf4j
public class UserComicsTask {

    @Autowired
    private UserBrowseHistoryMapper historyMapper;
    @Autowired
    private ComicsCollectMapper collectMapper;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 凌晨两点定时将用户历史记录存入数据库中
     */
    @Scheduled(cron = "0 30 1 * * ?")
    private void insertComicsHistory() {
        Set<String> allKeys = redisUtils.getAllKeys(UserConst.USER_BROWSE_PRE + "*");
        for (String key : allKeys) {
            Map<Object, Object> historyJson = redisUtils.hGetAll(key);
            historyJson.forEach((comicsId, value) -> {
                UserBrowseHistory history = JSON.parseObject(value.toString(), UserBrowseHistory.class);
                if (history.getDeleted() == 0) {
                    QueryWrapper<UserBrowseHistory> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("user_id", history.getUserId()).eq("comics_id", comicsId);
                    UserBrowseHistory beforeHistory = historyMapper.selectOne(queryWrapper);
                    if (Objects.isNull(beforeHistory)) {
                        historyMapper.insert(history);
                        log.info("历史记录{} 加入数据库中", history);
                    } else {
                        if (!beforeHistory.getChapterId().equals(history.getChapterId())) {
                            UpdateWrapper<UserBrowseHistory> updateWrapper = new UpdateWrapper<>();
                            updateWrapper.eq("user_id", history.getUserId()).eq("comics_id", comicsId)
                                    .set("chapter_id", history.getChapterId());
                            historyMapper.update(null, updateWrapper);
                        }
                    }
                }
            });
        }
    }

    /**
     * 定时两点将超时的用户浏览记录删除
     * 删除内容包括用户已删除的历史记录和超过三十天的历史记录
     */
    @Scheduled(cron = "0 0 2 * * ?")
    private void deleteComicsHistory() {
        List<UserBrowseHistory> historyList = historyMapper.getExpireHistory(UserConst.USER_BROWSE_EXPIRE);
        for (UserBrowseHistory history : historyList) {
            historyMapper.deleteById(history.getHistoryId());
        }
        log.info("超过{}天的历史记录已清除完毕", UserConst.USER_BROWSE_EXPIRE);
        String historyKey = UserConst.USER_BROWSE_PRE + "*";
        Set<String> allKeys = redisUtils.getAllKeys(historyKey);
        for (String keys : allKeys) {
            Map<Object, Object> historyMap = redisUtils.hGetAll(keys);
            historyMap.forEach((key, value) -> {
                UserBrowseHistory history = JSON.parseObject(value.toString(), UserBrowseHistory.class);
                if (history.getDeleted() != 0) {
                    QueryWrapper<UserBrowseHistory> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("comics_id", history.getComicsId()).eq("user_id", history.getUserId());
                    historyMapper.delete(queryWrapper);
                    redisUtils.hDelete(keys, key);
                    log.info("用户:{},查看漫画:{}的记录已删除", history.getUserId(), history.getComicsId());
                }
            });
        }
    }

    /**
     * 定时四点修改数据库中用户收藏漫画的信息
     */
    @Scheduled(cron = "0 30 2 * * ?")
    private void insertComicsCollect() {
        Date now = new Date();
        Set<String> allKeys = redisUtils.getAllKeys(UserConst.USER_COLLECT_PRE + "*");
        ComicsCollect comicsCollect = new ComicsCollect();
        for (String key : allKeys) {
            Map<Object, Object> collectMap = redisUtils.hGetAll(key);
            Date gwtCreate = (Date) collectMap.get("gwtCreate");
            if (judgmentDate(gwtCreate, now)) {
                comicsCollect.setComicsId((Long) collectMap.get("comicsId"));
                comicsCollect.setUserId((Long) collectMap.get("userId"));
                comicsCollect.setGwtCreate((Date) collectMap.get("gwtCreate"));
                collectMapper.insert(comicsCollect);
                log.info("收藏记录:{} 已加入数据库中", JSON.toJSONString(comicsCollect));
            }
        }
    }

    /**
     * 定时三点删除用户删除的收藏漫画信息
     * @return
     */
    @Scheduled(cron = "0 0 3 * * ?")
    private void deleteComicsCollect() {
        Set<String> allKeys = redisUtils.getAllKeys(UserConst.USER_CANCEL_COLLECT + "*");
        for (String key : allKeys) {
            String[] s = key.split("_");
            String comicsId = redisUtils.get(s[s.length-1]);
            String userId = redisUtils.get(s[s.length-2]);
            QueryWrapper<ComicsCollect> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userId", userId).eq("comicsId", comicsId);
            collectMapper.delete(queryWrapper);
            redisUtils.delete(key);
            log.info("用户:{} 收藏漫画:{} 记录已删除", userId, comicsId);
        }
    }

    /**
     * 定时四点删除用户删除的历史记录信息
     * 删除内容包括用户已删除的历史记录和超过三十天的历史记录
     * @return
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void deleteBrowseHistory() {
        String historyKey = UserConst.USER_BROWSE_PRE + "*";

    }

    /**
     * 判断时间是否在24小时内
     * @param start
     * @param end
     * @return
     * @throws Exception
     */
    private boolean judgmentDate(Date start, Date end) {
        long cha = end.getTime() - start.getTime();
        if (cha < 0)
            return false;
        double result = cha * 1.0 / (1000 * 60 * 60);
        if (result <= 24)
            return true;
        else
            return false;
    }

}
